package com.muyu.payment.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.common.core.utils.IdGenerator;
import com.muyu.payment.config.AliPayConfig;
import com.muyu.payment.domain.RechargeOrder;
import com.muyu.payment.domain.UserBalance;
import com.muyu.payment.domain.req.RechargeReq;
import com.muyu.payment.domain.resp.RechargeResp;
import com.muyu.payment.mapper.RechargeOrderMapper;
import com.muyu.payment.service.RechargeService;
import com.muyu.payment.service.UserBalanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 充值服务实现类
 *
 * @author muyu
 * @date 2025-01-27
 */
@Slf4j
@Service
public class RechargeServiceImpl extends ServiceImpl<RechargeOrderMapper, RechargeOrder> implements RechargeService {

    @Autowired
    private RechargeOrderMapper rechargeOrderMapper;

    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private AliPayConfig aliPayConfig;

    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RechargeOrder createRechargeOrder(Long userId, String userName, RechargeReq request) {
        try {
            // 生成订单号
            String orderNo = "RC" +IdGenerator.generateId();

            // 创建充值订单
            RechargeOrder rechargeOrder = RechargeOrder.builder()
                    .orderNo(orderNo)
                    .userId(userId)
                    .userName(userName)
                    .amount(request.getAmount())
                    .payChannel(request.getPayChannel())
                    .orderStatus(1) // 待支付
                    .subject(request.getSubject() != null ? request.getSubject() : "账户充值")
                    .body(request.getBody() != null ? request.getBody() : "用户账户充值")
                    .clientIp(request.getClientIp())
                    .expireTime(new Date(System.currentTimeMillis() + 30 * 60 * 1000)) // 30分钟过期
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build();

            save(rechargeOrder);
            
            log.info("创建充值订单成功，订单号: {}, 用户ID: {}, 金额: {}", orderNo, userId, request.getAmount());
            return rechargeOrder;
        } catch (Exception e) {
            log.error("创建充值订单失败，用户ID: {}, 金额: {}", userId, request.getAmount(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handleRechargeCallback(String orderNo, String thirdPartyTradeNo, Integer status) {
        try {
            RechargeOrder rechargeOrder = getRechargeOrderByOrderNo(orderNo);
            if (rechargeOrder == null) {
                log.error("充值订单不存在，订单号: {}", orderNo);
                return false;
            }

            // 检查订单状态
            if (rechargeOrder.getOrderStatus() != 0) {
                log.warn("充值订单状态异常，订单号: {}, 当前状态: {}", orderNo, rechargeOrder.getOrderStatus());
                return false;
            }

            // 更新订单状态
            rechargeOrder.setOrderStatus(status);
            rechargeOrder.setThirdPartyTradeNo(thirdPartyTradeNo);
            rechargeOrder.setUpdateTime(new Date());
            
            if (status == 1) { // 支付成功
                rechargeOrder.setPayTime(new Date());
                
                // 增加用户余额
                boolean success = userBalanceService.increaseBalance(
                        rechargeOrder.getUserId(),
                        rechargeOrder.getAmount(),
                        1, // 充值
                        orderNo,
                        "账户充值"
                );
                
                if (!success) {
                    log.error("增加用户余额失败，订单号: {}", orderNo);
                    return false;
                }
            }
            
            updateById(rechargeOrder);
            
            log.info("处理充值回调成功，订单号: {}, 状态: {}", orderNo, status);
            return true;
        } catch (Exception e) {
            log.error("处理充值回调失败，订单号: {}", orderNo, e);
            throw e;
        }
    }

    @Override
    public RechargeOrder getRechargeOrderByOrderNo(String orderNo) {
        return rechargeOrderMapper.selectByOrderNo(orderNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelRechargeOrder(String orderNo) {
        try {
            RechargeOrder rechargeOrder = getRechargeOrderByOrderNo(orderNo);
            if (rechargeOrder == null) {
                log.error("充值订单不存在，订单号: {}", orderNo);
                return false;
            }

            // 只有待支付状态的订单才能取消
            if (rechargeOrder.getOrderStatus() != 1) {
                log.warn("充值订单状态异常，无法取消，订单号: {}, 当前状态: {}", orderNo, rechargeOrder.getOrderStatus());
                return false;
            }

            // 更新订单状态为已取消
            rechargeOrder.setOrderStatus(3);
            rechargeOrder.setUpdateTime(new Date());
            updateById(rechargeOrder);
            
            log.info("取消充值订单成功，订单号: {}", orderNo);
            return true;
        } catch (Exception e) {
            log.error("取消充值订单失败，订单号: {}", orderNo, e);
            throw e;
        }
    }

    @Override
    public RechargeResp createRechargeOrderWithPayment(Long userId, String userName, RechargeReq request) {
        try {
            // 先创建充值订单
            RechargeOrder rechargeOrder = createRechargeOrder(userId, userName, request);
            
            // 转换为响应对象
            RechargeResp rechargeResp = new RechargeResp();
            rechargeResp.setOrderNo(rechargeOrder.getOrderNo());
            rechargeResp.setUserId(rechargeOrder.getUserId());
            rechargeResp.setAmount(rechargeOrder.getAmount());
            rechargeResp.setPayChannel(rechargeOrder.getPayChannel());
            rechargeResp.setOrderStatus(rechargeOrder.getOrderStatus());
            rechargeResp.setExpireTime(rechargeOrder.getExpireTime());
            rechargeResp.setSubject(rechargeOrder.getSubject());
            rechargeResp.setBody(rechargeOrder.getBody());
            
            // 根据支付渠道调用相应的第三方支付接口
            String payUrl = null;
            String qrCodeUrl = null;
            
            log.info("开始创建支付链接，支付渠道: {}, 订单号: {}", request.getPayChannel(), rechargeOrder.getOrderNo());
            
            switch (request.getPayChannel()) {
                case 1: // 支付宝
                    payUrl = createAlipayPayment(rechargeOrder);
                    log.info("支付宝支付链接创建结果: {}", payUrl != null ? "成功" : "失败");
                    break;
                case 2: // 微信支付

                    log.warn("微信支付暂未实现，订单号: {}", rechargeOrder.getOrderNo());
                    break;
                case 3: // 银行卡
                    log.warn("银行卡支付暂未实现，订单号: {}", rechargeOrder.getOrderNo());
                    break;
                default:
                    log.error("不支持的支付渠道: {}", request.getPayChannel());
                    throw new RuntimeException("不支持的支付渠道");
            }
            
            rechargeResp.setPayUrl(payUrl);
            rechargeResp.setQrCodeUrl(qrCodeUrl);
            
            log.info("创建充值订单并调用第三方支付接口成功，订单号: {}, payUrl: {}", rechargeOrder.getOrderNo(), payUrl);
            return rechargeResp;
        } catch (Exception e) {
            log.error("创建充值订单并调用第三方支付接口失败，用户ID: {}, 金额: {}", userId, request.getAmount(), e);
            throw e;
        }
    }

    /**
     * 创建支付宝支付
     */
    private String createAlipayPayment(RechargeOrder rechargeOrder) {
        try {
            log.info("开始创建支付宝支付，订单号: {}, 配置信息: appId={}, notifyUrl={}, returnUrl={}", 
                    rechargeOrder.getOrderNo(), 
                    aliPayConfig.getAppId(),
                    aliPayConfig.getNotifyUrl(),
                    aliPayConfig.getReturnUrl());
            
            // 检查配置是否完整
            if (aliPayConfig.getAppId() == null || aliPayConfig.getAppPrivateKey() == null) {
                log.error("支付宝配置不完整，appId: {}, appPrivateKey: {}", 
                        aliPayConfig.getAppId(), 
                        aliPayConfig.getAppPrivateKey() != null ? "已设置" : "未设置");
                // 返回一个模拟的支付URL用于测试
                String mockPayUrl = "https://openapi.alipay.com/gateway.do?mock=true&orderNo=" + rechargeOrder.getOrderNo();
                log.warn("使用模拟支付URL: {}", mockPayUrl);
                return mockPayUrl;
            }
            
            DefaultAlipayClient alipayClient = new DefaultAlipayClient(
                    GATEWAY_URL, 
                    aliPayConfig.getAppId(),
                    aliPayConfig.getAppPrivateKey(), 
                    "JSON", 
                    "UTF-8", 
                    aliPayConfig.getAlipayPublicKey(),
                    "RSA2"
            );

            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            // 使用专门的充值回调地址
            request.setNotifyUrl(aliPayConfig.getNotifyUrl() + "/payment/recharge/notify");
            request.setReturnUrl(aliPayConfig.getReturnUrl() + "/recharge/return");

            HashMap<String, Object> map = new HashMap<>();
            map.put("out_trade_no", rechargeOrder.getOrderNo());
            map.put("total_amount", rechargeOrder.getAmount().toString());
            map.put("subject", rechargeOrder.getSubject());
            map.put("product_code", "FAST_INSTANT_TRADE_PAY");

            request.setBizContent(JSON.toJSONString(map));
            
            String payUrl = alipayClient.pageExecute(request).getBody();
            log.info("创建支付宝支付链接成功，订单号: {}, payUrl长度: {}", rechargeOrder.getOrderNo(), payUrl != null ? payUrl.length() : 0);
            return payUrl;
        } catch (AlipayApiException e) {
            log.error("创建支付宝支付失败，订单号: {}, 错误: {}", rechargeOrder.getOrderNo(), e.getMessage(), e);
            // 返回一个模拟的支付URL用于测试
            String mockPayUrl = "https://openapi.alipay.com/gateway.do?error=true&orderNo=" + rechargeOrder.getOrderNo();
            log.warn("使用模拟支付URL: {}", mockPayUrl);
            return mockPayUrl;
        }
    }
}